
/**********************************************************************************\
** 文件名称: mylist.c
** 创建人员: YCG
** 创建日期: 2018-12-14
** 文档描述: 双向列表
** 1.
** 版本代号: V0.1
** 版本说明: 初始版本
\********************************************************************************/
#include	"mylist.h"
#include	"uart.h"

/*******************************************************************************
** 函数名称: ListInit
** 功能描述: 初始化列表
** 参数说明: yList_t: [输入]  需要初始化的列表
** 返回说明: None
** 创建人员: YCG
** 创建日期: 2018-12-14
********************************************************************************/
void ListInit(MyList_t * const yList_t) {

    yList_t->Index = yList_t->EndItem;           //此时的地址指向本身

    yList_t->EndItem->Head  = yList_t;               //头部是本身
    yList_t->EndItem->Next  = yList_t->EndItem;   //表头的列表项的下一个指向表头的列表项本身
    yList_t->EndItem->Pre   = yList_t->EndItem;   //表头的列表项的上一个一个指向表头的列表项本身
    yList_t->EndItem->Value = LIST_VALUE_MAX;        //表头的列表项的值初始化为最大值

    yList_t->ListNum = 0U;                         //除了表头以外，列表项数量初始化为0
}

/*******************************************************************************
** 函数名称: ListItemInit
** 功能描述: 初始化列表项
** 参数说明: yItem: [输入] 需要初始化的列表项
** 返回说明: None
** 创建人员: YCG
** 创建日期: 2018-12-14
********************************************************************************/
void ListItemInit(MyListItem_t * const yItem) {
    yItem->Head = NULL;
}

/*******************************************************************************
** 函数名称: ListInsertEnd
** 功能描述: 插入列表项到列表当前位置的前面
** 参数说明: yList_t: [输入]   操作的列表
**			 yNewItem: [输入]    需要插入的列表项
** 返回说明: None
** 创建人员: YCG
** 创建日期: 2018-12-14
********************************************************************************/
void ListInsertEnd(MyList_t * const yList_t, MyListItem_t * const yNewItem) {
    MyListItem_t * const yItem = yList_t->Index;     //获取当前的位置

    if(yNewItem->Head == NULL) { //避免重复添加
        yNewItem->Next = yItem;        //新列表项的下一个是旧的列表项
        yNewItem->Pre  = yItem->Pre;   //新列表项的上一个是旧的列表项上一个

        yItem->Pre->Next = yNewItem;  //旧列表项的上一个的下一个是新列表项
        yItem->Pre = yNewItem;        //旧列表项的上一个是新列表项

        yNewItem->Head = yList_t;          //添加到列表中

        yList_t->ListNum += 1 ;          //列表中的列表项计数加一
    }
}

/*******************************************************************************
** 函数名称: ListInsert
** 功能描述: 按照列表项的值从大到小插入
** 参数说明: yList_t: [输入]    操作的列表
**			 yNewItem: [输入]     需要插入的列表项
** 返回说明: None
** 创建人员: YCG
** 创建日期: 2018-12-14
********************************************************************************/
void ListInsert(MyList_t * const yList_t, MyListItem_t * const yNewItem) {

    MyListItem_t *  yItem ;                       //操作的列表项对象
    const uint32_t yValue = yNewItem->Value;   //需要插入的列表项的值
    if(yNewItem->Head == NULL) { //避免重复添加
        if(yValue == LIST_VALUE_MAX) {              //避免进入死循环
            yItem = yList_t->EndItem->Pre;            //是最大值的话插入到末尾
        } else {
            //从第一个开始遍历列表，直到找到插入列表项的值大于的位置
            for(yItem = (yList_t->EndItem->Next); yItem->Value <= yValue; yItem = yItem->Next) {}
        }
        yNewItem->Next = yItem;       //新列表项的下一个是旧的列表项
        yNewItem->Pre = yItem->Pre;   //新列表项的上一个是旧的列表项上一个
        yItem->Pre->Next = yNewItem;  //旧列表项的上一个的下一个是新列表项
        yItem->Pre = yNewItem;        //旧列表项的上一个是新列表项

        yNewItem->Head = yList_t;          //添加到列表中

        yList_t->ListNum += 1 ;          //列表中的列表项计数加一
    }
}

/*******************************************************************************
** 函数名称: ListIRemove
** 功能描述: 移除对应的列表项
** 参数说明: yRemoveItem: [输入] 需要移除的列表项
** 返回说明: None
** 创建人员: YCG
** 创建日期: 2018-12-14
********************************************************************************/
void ListRemove(MyListItem_t * const yRemoveItem) {
    MyList_t * const yList_t = yRemoveItem->Head;
    if(yList_t != NULL) {       //避免是空的列表

        yRemoveItem->Next->Pre = yRemoveItem->Pre;        //移除列表项的下一个的前一个指向移除列表项的前一个
        yRemoveItem->Pre->Next = yRemoveItem->Next;       //移除列表项的前一个的下一个指向移除列表项的下一个

        if(yList_t->Index == yRemoveItem) {      //如果当前列表的索引指向移除列表项
            yList_t->Index = yRemoveItem->Pre;   //将索引指向移除列表项的前一个
        }
        yRemoveItem->Head = NULL;      //移除列表项的表头清空

        yList_t->ListNum -= 1 ;          //列表中的列表项计数减一
    }
}

/*******************************************************************************
** 函数名称: PrintList
** 功能描述: 打印列表
** 参数说明: yList_t: [输入] 需要打印的列表
** 返回说明: None
** 创建人员: YCG
** 创建日期: 2018-12-14
********************************************************************************/
void ListPrint(MyList_t * const yList_t) {

//    Uprintf("\r\n列表地址:   0x%-10x 列表数量:   %-5d\r\n", yList_t, yList_t->ListNum);

//    for(MyListItem_t* yList_Item = LIST_GET_HEAD(yList_t); LISTITEM_IS_NOT_END(yList_Item); LISTITEM_TO_NEXT(yList_Item)) {
//        Uprintf("列表项地址: 0x%-10x 列表项值: %-5d\r\n", yList_Item, yList_Item->Value);
//    }

}

/********************************End of File************************************/
